from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from datetime import datetime
from database import get_db
from models import NoFlyZone, User
from schemas import NoFlyZoneCreate, NoFlyZoneUpdate, NoFlyZoneSchema, ResponseModel, PaginatedResponse, DJINoFlyZoneResponse
from api.deps import get_current_active_user, get_current_superuser
import math

router = APIRouter()

@router.get("", response_model=ResponseModel[PaginatedResponse[NoFlyZoneSchema]])
def get_no_fly_zones(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    name: Optional[str] = Query(None, description="禁飞区名称搜索"),
    zone_type: Optional[str] = Query(None, description="禁飞区类型过滤"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """获取禁飞区列表"""
    query = db.query(NoFlyZone)
    
    if name:
        query = query.filter(NoFlyZone.name.contains(name))
    
    if zone_type:
        query = query.filter(NoFlyZone.zone_type == zone_type)
    
    # 计算总数
    total = query.count()
    
    # 分页
    no_fly_zones = query.offset((page - 1) * page_size).limit(page_size).all()
    
    return ResponseModel(
        data=PaginatedResponse(
            total=total,
            page=page,
            page_size=page_size,
            items=no_fly_zones
        )
    )

@router.get("/{no_fly_zone_id}", response_model=ResponseModel[NoFlyZoneSchema])
def get_no_fly_zone(
    no_fly_zone_id: int,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """获取禁飞区详情"""
    no_fly_zone = db.query(NoFlyZone).filter(NoFlyZone.id == no_fly_zone_id).first()
    
    if not no_fly_zone:
        raise HTTPException(status_code=404, detail="禁飞区不存在")
    
    return ResponseModel(data=no_fly_zone)

@router.post("", response_model=ResponseModel[NoFlyZoneSchema])
def create_no_fly_zone(
    no_fly_zone_data: NoFlyZoneCreate,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """创建禁飞区"""
    # 检查名称是否已存在
    existing_zone = db.query(NoFlyZone).filter(NoFlyZone.name == no_fly_zone_data.name).first()
    if existing_zone:
        raise HTTPException(status_code=400, detail="禁飞区名称已存在")
    
    # 创建新禁飞区
    no_fly_zone = NoFlyZone(**no_fly_zone_data.dict())
    
    # 保存到数据库
    db.add(no_fly_zone)
    db.commit()
    db.refresh(no_fly_zone)
    
    return ResponseModel(data=no_fly_zone, message="禁飞区创建成功")

@router.put("/{no_fly_zone_id}", response_model=ResponseModel[NoFlyZoneSchema])
def update_no_fly_zone(
    no_fly_zone_id: int,
    no_fly_zone_data: NoFlyZoneUpdate,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """更新禁飞区"""
    # 查找禁飞区
    no_fly_zone = db.query(NoFlyZone).filter(NoFlyZone.id == no_fly_zone_id).first()
    
    if not no_fly_zone:
        raise HTTPException(status_code=404, detail="禁飞区不存在")
    
    # 检查名称是否已存在（如果更新了名称）
    if no_fly_zone_data.name and no_fly_zone_data.name != no_fly_zone.name:
        existing_zone = db.query(NoFlyZone).filter(NoFlyZone.name == no_fly_zone_data.name).first()
        if existing_zone:
            raise HTTPException(status_code=400, detail="禁飞区名称已存在")
    
    # 更新禁飞区属性
    update_data = no_fly_zone_data.dict(exclude_unset=True)
    for field, value in update_data.items():
        setattr(no_fly_zone, field, value)
    
    # 更新时间
    no_fly_zone.updated_at = datetime.now()
    
    # 保存到数据库
    db.commit()
    db.refresh(no_fly_zone)
    
    return ResponseModel(data=no_fly_zone, message="禁飞区更新成功")

@router.delete("/{no_fly_zone_id}", response_model=ResponseModel[dict])
def delete_no_fly_zone(
    no_fly_zone_id: int,
    current_user: User = Depends(get_current_superuser),
    db: Session = Depends(get_db)
) -> Any:
    """删除禁飞区"""
    # 查找禁飞区
    no_fly_zone = db.query(NoFlyZone).filter(NoFlyZone.id == no_fly_zone_id).first()
    
    if not no_fly_zone:
        raise HTTPException(status_code=404, detail="禁飞区不存在")
    
    # 删除禁飞区
    db.delete(no_fly_zone)
    db.commit()
    
    return ResponseModel(message="禁飞区删除成功", data={"id": no_fly_zone_id})

@router.get("/dji/compatible", response_model=DJINoFlyZoneResponse)
def get_dji_compatible_no_fly_zones(
    ltlat: float = Query(..., description="左上角纬度"),
    ltlng: float = Query(..., description="左上角经度"),
    rblat: float = Query(..., description="右下角纬度"),
    rblng: float = Query(..., description="右下角经度"),
    zones_mode: str = Query("total", description="区域模式"),
    drone: str = Query(None, description="无人机类型"),
    level: str = Query(None, description="区域级别"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """获取与DJI API兼容的禁飞区数据 - 模仿DJI flysafe-api接口格式"""
    # 查找所有禁飞区
    all_zones = db.query(NoFlyZone).all()
    
    # 当前时间
    now = datetime.now()
    
    # 过滤出在时间范围内的禁飞区
    valid_zones = []
    for zone in all_zones:
        # 检查时间范围（如果设置了）
        if zone.start_time and now < zone.start_time:
            continue
        if zone.end_time and now > zone.end_time:
            continue
        valid_zones.append(zone)
    
    # 转换为DTO对象
    zone_schemas = [NoFlyZoneSchema.from_orm(zone) for zone in valid_zones]
    
    # 使用DJINoFlyZoneResponse.from_no_fly_zones方法转换为DJI API兼容格式
    return DJINoFlyZoneResponse.from_no_fly_zones(zone_schemas)

@router.get("/check_position", response_model=ResponseModel[dict])
def check_position_in_no_fly_zone(
    latitude: float = Query(..., description="纬度"),
    longitude: float = Query(..., description="经度"),
    altitude: float = Query(0.0, description="高度（米）"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
) -> Any:
    """检查指定位置是否在禁飞区内"""
    from math import radians, cos, sin, asin, sqrt
    
    # 查找所有禁飞区
    all_zones = db.query(NoFlyZone).all()
    
    # 当前时间
    now = datetime.now()
    
    # 检查是否在禁飞区内
    in_no_fly_zone = False
    violating_zones = []
    
    for zone in all_zones:
        # 检查时间范围（如果设置了）
        if zone.start_time and now < zone.start_time:
            continue
        if zone.end_time and now > zone.end_time:
            continue
        
        # 检查高度范围
        if altitude < zone.min_altitude or altitude > zone.max_altitude:
            continue
        
        # 根据禁飞区类型检查位置
        if zone.zone_type == "circle":
            # 计算两点间距离（使用Haversine公式）
            # 将十进制度数转换为弧度
            lon1, lat1, lon2, lat2 = map(radians, [longitude, latitude, zone.center_longitude, zone.center_latitude])
            
            # Haversine公式
            dlon = lon2 - lon1 
            dlat = lat2 - lat1 
            a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
            c = 2 * asin(sqrt(a)) 
            r = 6371  # 地球半径（公里）
            distance = c * r * 1000  # 转换为米
            
            if distance <= zone.radius:
                in_no_fly_zone = True
                violating_zones.append(zone.name)
        
        elif zone.zone_type == "polygon" and zone.coordinates:
            # 简化的多边形包含检查算法（射线法）
            # 注意：这是一个简化实现，实际应用中可能需要更复杂的几何计算库
            # 这里仅作为示例
            points = [(coord['lat'], coord['lng']) for coord in zone.coordinates]
            inside = False
            n = len(points)
            
            for i in range(n):
                j = (i + n - 1) % n
                xi, yi = points[i]
                xj, yj = points[j]
                
                intersect = ((yi > latitude) != (yj > latitude)) and \
                           (longitude < (xj - xi) * (latitude - yi) / (yj - yi) + xi)
                
                if intersect:
                    inside = not inside
            
            if inside:
                in_no_fly_zone = True
                violating_zones.append(zone.name)
    
    return ResponseModel(
        data={
            "in_no_fly_zone": in_no_fly_zone,
            "violating_zones": violating_zones
        }
    )